//
// Created by Sivin on 2024/5/11.
//

#include "RtspInput.h"


RtspInput::RtspInput(std::string url) : url_(std::move(url)) {
}

RtspInput::~RtspInput() {
  if (fmtCtx_ != nullptr) {
    avformat_close_input(&fmtCtx_);
    fmtCtx_ = nullptr;
  }
}

int RtspInput::Open() {
  printf("start open url:%s\n", url_.c_str());
  avformat_network_init();
  AVDictionary *options = nullptr;
  av_dict_set(&options, "rtsp_transport", "tcp", 0);
  int ret = avformat_open_input(&fmtCtx_, url_.c_str(), nullptr, &options);
  if (ret < 0) {
    av_log(nullptr, AV_LOG_ERROR, "Cannot open input file\n");
    return -1;
  }
  printf("start find media stream info.\n");
  ret = avformat_find_stream_info(fmtCtx_, nullptr);
  if (ret < 0) {
    av_log(nullptr, AV_LOG_ERROR, "Cannot find stream information\n");
    return -1;
  }

  videoStreamIndex_ = av_find_best_stream(fmtCtx_, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
  AVStream *inVideoStream = fmtCtx_->streams[videoStreamIndex_];
  int frameRate = inVideoStream->r_frame_rate.num/inVideoStream->r_frame_rate.den;
  printf("Get stream info success frameRate:%d\n", frameRate);
  return 0;
}

int RtspInput::ReadPacket(MediaPacket &packet) {
  int ret = av_read_frame(fmtCtx_, &packet.pkt);
  if (ret < 0) {
    return -1;
  }
  packet.isVideo = packet.pkt.stream_index == videoStreamIndex_;
  packet.isKeyFrame = packet.pkt.flags & AV_PKT_FLAG_KEY;
  return 0;
}

AVRational &RtspInput::GetTimeBase() {
  return fmtCtx_->streams[videoStreamIndex_]->time_base;
}

AVCodecParameters *RtspInput::GetCodecPar() {
  return fmtCtx_->streams[videoStreamIndex_]->codecpar;
}